package cn.zhenglili.uflodemo.controller;

import cn.zhenglili.uflodemo.service.BusinessService;
import cn.zhenglili.uflodemo.utils.Result;
import com.bstek.uflo.console.handler.impl.list.AssigneeInfo;
import com.bstek.uflo.console.provider.ProcessFile;
import com.bstek.uflo.console.provider.ProcessProvider;
import com.bstek.uflo.console.provider.ProcessProviderUtils;
import com.bstek.uflo.process.assign.AssigneeProvider;
import com.bstek.uflo.process.assign.Entity;
import com.bstek.uflo.process.assign.PageQuery;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName：BusinessDesignerController
 * @Description：对文件进行操作，流程图设计,未涉及数据库，文件存在指定文件夹
 * @Author：zhenglili
 * @Date：2020/9/3 17:45
 * 流程设计地址：http://localhost:8080/uflo/designer
 **/
@Slf4j
@RestController
@RequestMapping("/admin/designer")
public class BusinessDesignerController {

    @Autowired
    private BusinessService businessService;

    // 获取Spring中的bean,bean相当于一个类中自定义了一个实例，但是没有变量名，仍在spring容器中，当使用时，直接调用
    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 获取所有文件分类列表,此时文件系统中只有：默认文件系统一种分类
     * @return
     */
    @ApiOperation("获取所有文件分类列表")
    @GetMapping("load-process-providers")
    public Result loadProcessProviders(){
        Result result = new Result();
        // 获取所有流程文件的统一类别,一类对应一个ProcessProvider，一个ProcessProvider对应多个流程文件
        List<ProcessProvider> providers = ProcessProviderUtils.getProviders();
        result.setSuccess(true);
        result.setResult(providers);
        return result;
    }

    /**
     * 查看分类对应的文件名和创建时间
     * @param providerName
     * @return
     * @throws IOException
     */
    @ApiOperation("查看分类对应的文件名和创建时间")
    @GetMapping("load-process-provider-files")
    public Result loadProcessProviderFiles(@RequestParam String providerName) {
        log.info("enter into /load-process-provider-files");
        log.info("文件分类名:"+providerName);
        Result result = new Result();
        ProcessProvider processProvider = ProcessProviderUtils.getProcessProviderByName(providerName);
        // 根据processProvider获取对应的文件
        List<ProcessFile> files = processProvider.loadAllProcesses();
        result.setSuccess(true);
        result.setResult(files);
        return result;
    }

    /**
     * 检查流程文件名是否存在
     * @param fileName
     * @return
     */
    @ApiOperation("检查流程文件名是否存在")
    @GetMapping("check-file-name-exist")
    public Result checkFileNameExist(@RequestParam String fileName){
        log.info("enter into /check-file-name-exist&fileName="+fileName);
        boolean flag = businessService.fileNameIsExist(fileName);
        if(flag){
            // 文件名存在
            return Result.error(500,"文件名已存在");
        }
        return Result.ok("文件名不存在");
    }

    /**
     * 删除文件
     * @param fileName
     * fileName格式 file:xxx.uflo.xml
     */
    @ApiOperation("删除文件")
    @DeleteMapping("delete-file")
    public Result deleteFile(@RequestParam String fileName){
        log.info("enter into /delete-file&fileName=" + fileName);
        businessService.deleteFile(fileName);
        return Result.ok("删除文件成功");
    }

    /**
     * 获取可选择的参与者列表，如果providerKey为空返回类型，如果不为空，搜索内部的用户
     * @param pageNo
     * @param pageSize
     * @param providerKey 是一个准确的值
     * @param keyWord
     * @return
     */
    @ApiOperation("获取可选择的参与者列表")
    @GetMapping("assignProviders")
    public Result assignProviders(Integer pageNo,
                                        Integer pageSize,
                                        String providerKey,
                                        String keyWord){
        //获取可选的参与者类型provider
        Map<String, AssigneeProvider> assigneeProviderMap = businessService.assigneeProviderMap(applicationContext);

        // 根据类型查询可选参与人列表，传入的providerKey为空则返回类型信息
        if(StringUtils.isEmpty(providerKey)){
            // providerKey为空
            // 类型为空，查询类型列表，以List<InheritAssigneeInfo>,但InheritAssigneeInfo内部的list人员具体信息为空
            List<AssigneeInfo> noDetailsList = new ArrayList<>();
            for(String key : assigneeProviderMap.keySet()){
                // 根据类型key设置类型基本信息
                AssigneeInfo info = businessService.bulidAssigneeInfo(assigneeProviderMap,key);
                noDetailsList.add(info);
            }
            return Result.ok(noDetailsList);
        }else{
            // 设置分页参数
            PageQuery<Entity> pageQuery = new PageQuery<>(pageNo,pageSize);
            AssigneeInfo assigneeInfoDetails = businessService.buildAssigneeInfoDetails(assigneeProviderMap,providerKey,pageQuery,keyWord);
            return Result.ok(assigneeInfoDetails);
        }

    }

    @ApiOperation("保存流程模板文件")
    @PostMapping("save-file")
    public Result saveFile(@RequestParam String fileName, @RequestParam String content) {
        content = businessService.decode(content);
        ProcessProvider provider = ProcessProviderUtils.getProcessProvider(fileName);
        provider.saveProcess(fileName, content);
        return Result.ok();
    }
}
